package com.apestech.framework.util.modul;

import com.alibaba.druid.pool.DruidDataSource;
import com.apestech.framework.util.LocalVariable;
import com.apestech.framework.xml.plugin.XmlPaste;
import com.apestech.framework.xml.plugin.modul.Database;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngineConfiguration;

import java.sql.SQLException;
import java.util.Hashtable;

/**
 * @author hup
 * @create 2018-08-30-19:24
 */
public class DBList {

    private Hashtable<String, DBInfo> single=new Hashtable<String, DBInfo>();  //不重复数据集
    private Hashtable<String, DBInfo> sysDB=new Hashtable<String, DBInfo>();   //定义数据集
    private Hashtable<String, String> dbmap=new Hashtable<String, String>();   //数据集id之间的mapping
    private Hashtable<String, ProcessEngine> sysEngine=new Hashtable<String, ProcessEngine>();   //数据集id之间的mapping
    private String singleDBName;

    public String add(DruidDataSource dataSource) throws Exception {
        return getDBInfo(dataSource, null).getDbName();
    }

    public String add(DruidDataSource dataSource, String db) throws Exception {
        return getDBInfo(dataSource, db).getDbName();
    }

    public void add(String db) throws Exception {
        getDBInfo(null, db);
    }

    public DBInfo getDBInfo(String db) throws Exception {
        if(db==null){
            throw new Exception("当前dbname为空，请检查代码逻辑！");
        }
        String id=dbmap.get(db);
        if(id==null){
            getDBInfo(null, db);
        }
        id=dbmap.get(db);
        return single.get(id);
    }

    public DBInfo getDBInfo(DruidDataSource dataSource) throws Exception {
        DBInfo info=getDBInfo(dataSource, null);
        return single.get(info.getId());
    }

    public DruidDataSource getDataSource(String db) throws Exception {
        return getDBInfo(db).getDataSource();
    }

    public int size(){
        return single.size();
    }

    public String getSingleDBName() {
        return singleDBName;
    }

    private DBInfo getDBInfo(DruidDataSource dataSource, String db) throws Exception {
        DBInfo info=null;
        if(db!=null){
            info=sysDB.get(db);
        }
        if(info==null){
            DruidDataSource ds=null;
            if(dataSource!=null) ds=dataSource;
            if(ds==null && db!=null){
                ds=addDs(db);
            }
            if(ds==null){
                throw new SQLException("当前没有符合条件的数据库数据，请检查代码入参是否正常！");
            }
            info=new DBInfo(ds, db);
            if(db==null){
                db=info.getDbName();
            }
            info=setSysDB(db, info);
        }
        setSingle(db, info);
        return info;
    }

    private DBInfo setSysDB(String db, DBInfo info){
        DBInfo info1=sysDB.get(db);
        if(info1!=null) return info1;
        else {
            sysDB.put(db, info);
            return info;
        }
    }

    private void setSingle(String db, DBInfo info){
        singleDBName=db;
        if(dbmap.get(db)==null) dbmap.put(db, info.getId());
        DBInfo info_single=single.get(info.getId());
        if(info_single==null){
            single.put(info.getId(), info);
        }
    }

    private DruidDataSource addDs(String db) throws Exception {
        Database.DB dbconf=getConfigDatabase(db);
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName("oracle.jdbc.driver.OracleDriver");
        ds.setUrl("jdbc:oracle:thin:@"+dbconf.getUrl());
        ds.setUsername(dbconf.getUsername());
        ds.setPassword(dbconf.getPassword());
        ds.setInitialSize(5);
        ds.setMinIdle(1);
        ds.setMaxActive(10);
        ds.setFilters("stat");
        ds.setPoolPreparedStatements(false);
        return ds;
    }

    private Database.DB getConfigDatabase(String db) throws Exception {
        return LocalVariable.getConfig().getConfigDatabase(db);
    }

    public ProcessEngine getEngine(String db) throws Exception {
        String id=dbmap.get(db);
        ProcessEngine engine=null;
        if(id!=null){
            engine=sysEngine.get(id);
        }
        if(engine==null){
            DruidDataSource ds=getDataSource(db);
            if(ds==null){
                throw new Exception("数据库没有初始化，请检查代码逻辑！");
            }
            ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
            processEngineConfiguration.setDataSource(ds);
            engine = processEngineConfiguration.buildProcessEngine();
            //engine.close();
            if(id==null) id=db;
            sysEngine.put(id, engine);
        }
        return engine;
    }

}
